package com.joycessh.templates;

import com.joycessh.common.template.DirectiveHandler;
import com.joycessh.common.template.TemplateDirective;
import com.joycessh.entity.Post;
import com.joycessh.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author Joycessh
 * @Description 本周热议
 * @Date 8/21/19 2:20 PM
 */
@Component
public class HotsTemplate extends TemplateDirective {

    // 获取文章的默认数量
    private static final long hotPostsSize = 6L;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public String getName() {
        return "hots";
    }

    @Override
    public void execute(DirectiveHandler handler) throws Exception {

        List<Map<String, Object>> hotPosts = new ArrayList<>();

//        hotPosts = getHotPosts(6);
        hotPosts = ensureHotPosts(hotPostsSize);
        handler.put(RESULTS, hotPosts).render();

    }

    /**
     * 热点评论数量的适配策略
     *
     * @author Joycessh
     * @param n
     * @return java.util.List
     * @date 8/23/19 8:13 PM
     */
    private List ensureHotPosts(long n) {
        if (n <= 0) {
            return null;
        }

        long rankSize = redisUtil.getZsetSize("last_week_rank");
//        System.out.println(rankSize);

        if (n >= rankSize) {
            return getHotPosts(n);
        }

        List<Map<String, Object>> hotPosts = new ArrayList<>();
        hotPosts = getHotPosts(n);

        if (hotPosts.size() < hotPostsSize) {
            long newRank = n * 2 - hotPosts.size();
            return ensureHotPosts(newRank);
        }
        return hotPosts;
    }

    /**
     * 取出zset中前n个元素，排除了已删除的文章
     *
     * @author Joycessh
     * @param n
     * @return java.util.List
     * @date 8/23/19 8:13 PM
     */
    private List getHotPosts(long n) {

        Set<ZSetOperations.TypedTuple> lastWeekRank = redisUtil.getZSetRank("last_week_rank", 0, n);

        List<Map<String, Object>> hotPosts = new ArrayList<>();
        for (ZSetOperations.TypedTuple typedTuple : lastWeekRank) {

            // 文章删除后，清空了缓存，判断一下
            if (redisUtil.hasKey("rank_post_" + typedTuple.getValue())) {
                Map<String, Object> map = new HashMap<>();
                map.put("comment_count", typedTuple.getScore());
                map.put("id", redisUtil.hget("rank_post_" + typedTuple.getValue(), "post:id"));
                map.put("title", redisUtil.hget("rank_post_" + typedTuple.getValue(), "post:title"));
                hotPosts.add(map);
            }

        }
        return hotPosts;
    }

}
